package cn.school.common.utils;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;



import org.apache.commons.codec.digest.DigestUtils;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;

import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;

import org.apache.http.entity.StringEntity;

import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class HttpClientUtil {

	private static final Logger logger =   LogManager.getLogger(HttpClientUtil.class);

	
	/**
	 * 创建http头信息
	 * 
	 * @return
	 */
	public static Header[] createHeads() {
		Header header = new BasicHeader("code", DigestUtils.md5Hex("LZSHlzsh123"));
		Header headerJson = new BasicHeader("Content-Type", "application/json");
		Header headerVersion = new BasicHeader("appVersion", "1");
		Header appDevice = new BasicHeader("appDevice", "Server");
		Header[] headers = { header, headerJson, appDevice, headerVersion};
		return headers;
	}
	
	public static Header[] createDouyinHeads() {
		Header header = new BasicHeader("Content-Type", "multipart/form-data;charset=utf-8;boundart=__X_PAW_BOUNDARY__");
		Header[] headers = { header};
		return headers;
	}
	
	public static byte[] getFileStream(String filePath) {
		byte[] buffer = null;
		File file = new File(filePath);
		FileInputStream fis;
		try {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			fis = new FileInputStream(file);
			byte[] b = new byte[1024];
			int n;
			while ((n = fis.read(b)) != -1) {
				bos.write(b, 0, n);
			}
			fis.close();
			bos.close();
			buffer = bos.toByteArray();
//			if(file.exists()) {
//				file.delete();
//			}
		} catch (FileNotFoundException e) {
		e.printStackTrace();
		}catch (IOException e) {
		e.printStackTrace();
		}
		return buffer;
		}

	

	
	

	
	
	public static Map httpBodyPost(String url, String jsonStr, Header[] headers) {
		logger.info("HttpClintUtil httpPost param: url=" + url + ",jsonStr=" + jsonStr);
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);
		/*RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(3000).setConnectionRequestTimeout(3000)
				.setSocketTimeout(3000).setRedirectsEnabled(true).build();*/
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(6000).setSocketTimeout(10000).build();
		
		CloseableHttpResponse response = null;
		httpPost.setConfig(requestConfig);
		Map resultMap = new HashMap();
		try {
			for (Header header : headers) {
				httpPost.addHeader(header);
			}

			StringEntity entity = new StringEntity(jsonStr, "UTF-8");
			
			// post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
			httpPost.setEntity(entity);
			response = httpClient.execute(httpPost);
			logger.info("HttpClintUtil httpPost response" + response);
			int statusCode = response.getStatusLine().getStatusCode();
			HttpEntity responseEntity = response.getEntity();
			String responseContent = EntityUtils.toString(responseEntity, "UTF-8");
			//需要转换处理unicode编码问题
			JSONObject json = JSONObject.parseObject(responseContent);
			logger.info("HttpClintUtil httpPost responseContent" + json.toJSONString());
			resultMap.put("statusCode", statusCode);
			resultMap.put("responseContent", json.toJSONString());
			if (statusCode != HttpStatus.SC_OK) {
				logger.error("HttpClintUtil httpPost post error,url:" + url + ",param:" + jsonStr + ",responseContent:"
						+ responseContent);
			}
			return resultMap;
		} catch (Exception e) {
			logger.error("HttpClintUtil httpPost is error,url:" + url + ",param:" + jsonStr, e);
			Throwable th = new Throwable("HttpClintUtil httpPost is error,url:" + url + ",param:" + jsonStr, e);
			resultMap.put("statusCode", 500);
			return resultMap;
		} finally {
			if (null != httpClient) {
				try {
					httpClient.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 发送post请求 含封装from表单请求参数DATA
	 * 
	 * @param url
	 * @param param
	 * @param headers
	 * @return
	 */
	public static Map httpPost(String url, String jsonStr, Header[] headers) {
		logger.info("HttpClintUtil httpPost param: url:{} , jsonStr:{}" , url ,jsonStr);
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(3000).setConnectionRequestTimeout(3000)
				.setSocketTimeout(3000).setRedirectsEnabled(true).build();
		CloseableHttpResponse response = null;
		httpPost.setConfig(requestConfig);
		Map resultMap = new HashMap();
		try {
			for (Header header : headers) {
				httpPost.addHeader(header);
			}

			List<BasicNameValuePair> pairList = new ArrayList<BasicNameValuePair>();
			pairList.add(new BasicNameValuePair("data", jsonStr));

			httpPost.setEntity(new UrlEncodedFormEntity(pairList, "utf-8"));

			response = httpClient.execute(httpPost);
			logger.info("HttpClintUtil httpPost response:{}" , response);
			int statusCode = response.getStatusLine().getStatusCode();
			HttpEntity responseEntity = response.getEntity();
			String responseContent = EntityUtils.toString(responseEntity, "UTF-8");
			//需要转换处理unicode编码问题
			JSONObject json = JSONObject.parseObject(responseContent);
			logger.info("HttpClintUtil httpPost responseContent" + json.toJSONString());
			resultMap.put("statusCode", statusCode);
			resultMap.put("responseContent", responseContent);
			if (statusCode != HttpStatus.SC_OK) {
				logger.error("HttpClintUtil httpPost post error,url:{} , responseContent:{}" , url ,responseContent);
			}
			return resultMap;
		} catch (Exception e) {
			logger.error("HttpClintUtil httpPost is error,url:{},param:{} , errMessage:{}" , url ,jsonStr, e);
			Throwable th = new Throwable("HttpClintUtil httpPost is error,url:" + url + ",param:" + jsonStr, e);
			resultMap.put("statusCode", 500);
			return resultMap;
		} finally {
			if (null != httpClient) {
				try {
					httpClient.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 发送post请求 含封装from表单请求参数
	 * 
	 * @param url
	 * @param param
	 * @param headers
	 * @return
	 */
	public static Map httpPostFrom(String url, Map<String, String> param, Header[] headers) {
		logger.info("HttpClintUtil httpPostFrom param: url={} , param:{}" , url ,param);
		String paramStr = JSONObject.toJSONString(param);
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(3000).setConnectionRequestTimeout(3000)
				.setSocketTimeout(3000).setRedirectsEnabled(true).build();
		CloseableHttpResponse response = null;
		httpPost.setConfig(requestConfig);
		// httpPost.setHeader("Content-Type","application/json");
		Map resultMap = new HashMap();
		try {
			if (headers != null) {
				for (Header header : headers) {
					httpPost.addHeader(header);
				}
			}

			List<BasicNameValuePair> pairList = new ArrayList<BasicNameValuePair>();
			for (String key : param.keySet()) {
				pairList.add(new BasicNameValuePair(key, param.get(key)));
			}

			httpPost.setEntity(new UrlEncodedFormEntity(pairList, "utf-8"));
			response = httpClient.execute(httpPost);
			logger.info("HttpClintUtil httpPostFrom response:{}" , response);
			int statusCode = response.getStatusLine().getStatusCode();
			HttpEntity responseEntity = response.getEntity();
			String responseContent = EntityUtils.toString(responseEntity, "UTF-8");
			logger.info("HttpClintUtil httpPostFrom responseContent:{}" , responseContent);
			resultMap.put("statusCode", statusCode);
			resultMap.put("responseContent", responseContent);
			if (statusCode != HttpStatus.SC_OK) {
				logger.error("HttpClintUtil httpPostFrom post error,url:{} , param:{} , responseContent:{}" , url ,param
						,responseContent);
			return resultMap;
			}
		} catch (Exception e) {
			logger.error("HttpClintUtil httpPostFrom is error,url:{} , param:{} , errMessage:{}" , url ,param , e);
			Throwable th = new Throwable("HttpClintUtil httpPostFrom is error,url:" + url + ",param:" + param, e);
			resultMap.put("statusCode", 500);
			return resultMap;
		} finally {
			if (null != httpClient) {
				try {
					httpClient.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return resultMap;
	}
	
	/**
	 * 微信支付请求方式
	 * 
	 * @return
	 */
	public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {
		logger.info("WeiXinPayCommonUtil httpsRequest param:requestUrl={} , requestmethod：{} ,outputStr:{}" , requestUrl 
				,requestMethod,outputStr);
		try {
			URL url = new URL(requestUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			conn.setRequestMethod(requestMethod);
			conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
			// 当outputStr不为null时向输出流写数据
			if (null != outputStr) {
				OutputStream outputStream = conn.getOutputStream();
				// 注意编码格式
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}
			// 从输入流读取返回内容
			InputStream inputStream = conn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			StringBuffer buffer = new StringBuffer();
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			// 释放资源
			bufferedReader.close();
			inputStreamReader.close();
			inputStream.close();
			inputStream = null;
			conn.disconnect();
			return buffer.toString();
		} catch (ConnectException ce) {
			logger.error("WeiXinPayCommonUtil httpsRequest conn time out,param::{} ,errMessahe:{}",outputStr, ce);
			ce.printStackTrace();
		} catch (Exception e) {
			logger.error("WeiXinPayCommonUtil httpsRequest https req error,param:{}, errmessage:{}" , outputStr, e);
			e.printStackTrace();
		}finally {
		}
		return null;
	}

	/**
	 * 发送get请求
	 * 
	 * @param url
	 * @return
	 */
	public static Map doGet(String url) {
		logger.info("HttpClintUtil doGet param url:{}" , url);
		Map resultMap = new HashMap();
		CloseableHttpClient httpCilent = HttpClients.createDefault();
		RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(3000) // 设置连接超时时间
				.setConnectionRequestTimeout(3000) // 设置请求超时时间
				.setSocketTimeout(3000).setRedirectsEnabled(true)// 默认允许自动重定向
				.build();
		HttpGet httpGet = new HttpGet(url);
		httpGet.setConfig(requestConfig);
		try {
			HttpResponse httpResponse = httpCilent.execute(httpGet);
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				String srtResult = EntityUtils.toString(httpResponse.getEntity());// 获得返回的结果
				resultMap.put("responseContent", srtResult);
			}
			resultMap.put("statusCode", httpResponse.getStatusLine().getStatusCode());
		} catch (IOException e) {
			Throwable th = new Throwable("HttpClintUtil doGet is error,url:" + url, e);
			resultMap.put("statusCode", 500);
			logger.error("HttpClintUtil doGet is error,url:{}, errMessage:{}" ,url, e);
		} finally {
			try {
				httpCilent.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return resultMap;
	}
	
	public static JsonObject httpGetGo(String getUrl, Map<String, String> parameterMap) throws Exception {
        String param = getSortedUrl(parameterMap);
        getUrl = getUrl + "?" + param;

        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(getUrl);
        httpGet.addHeader("Content-type","application/json; charset=utf-8");
        httpGet.setHeader("Accept", "application/json");
        
        SSLSocketFactory.getSocketFactory().setHostnameVerifier(new AllowAllHostnameVerifier());
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        //向微信发送请求并获取response
        String response = httpClient.execute(httpGet,responseHandler);
        logger.info(response);
        JsonParser parser = new JsonParser();
        JsonObject jsonObject = (JsonObject) parser.parse(response);
        /*//判断数据源
        String dataSrc = String.valueOf(parameterMap.get("dataSrc"));
        if(ConstantUtil.CLIENT_TYPE_APP.equals(dataSrc)){
        	
        }else{
        	 String session_key = jsonObject.get("session_key").getAsString();
             String openId = jsonObject.get("openid").getAsString();
             logger.info("c:"+openId+",session_key:"+session_key);
        }*/
        
        return jsonObject;
    }
	
	/**
	 * 请求微信服务
	 * @param getUrl
	 * @param parameterMap
	 * @return
	 * @throws Exception
	 */
	public static JsonObject httpRequestWXService(String getUrl, Map<String, String> parameterMap) throws Exception {
		String param = getSortedUrl(parameterMap);
        getUrl = getUrl + "?" + param;

        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(getUrl);
        SSLSocketFactory.getSocketFactory().setHostnameVerifier(new AllowAllHostnameVerifier());
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        //向微信发送请求并获取response
        String response = httpClient.execute(httpGet,responseHandler);
        JsonParser parser = new JsonParser();
        return (JsonObject) parser.parse(response);
	}
	
	/**
     * 将请求map中的转换成安装key排序的url
     * @param parameterMap
     * @return
     */
    public static String getSortedUrl(Map parameterMap) {
        // 排序
        Map<String, String> map = new TreeMap<String, String>(parameterMap);

        Set<String> keySet = map.keySet();
        StringBuilder sb = new StringBuilder();
        for (String key : keySet) {
            sb.append(key).append("=").append(map.get(key)).append("&");
        }
        String str = sb.substring(0, sb.length() - 1);
        return str;
    }
}
